﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using iTeachSoft.CoreObjects.win32.MsdnMag;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace iTeachSoft.CoreObjects.Recording
{
    public enum EnumRecordingStatus
    {
        InProgress,
        Paused,
        Stopped
    }

    public class RecordingManager
    {
        private const int VK_SNAPSHOT = 0x2C;

        private static EnumRecordingStatus mStatus = EnumRecordingStatus.Stopped;
        private static List<Bitmap> mImages = new List<Bitmap>();

        private static WindowsHooks mKeyboardHook = null;
        private static WindowsHooks mMouseHook = null;

        private static RecordSettings RecordSettings { get; set; }

        private static WindowsHooks CurrentWindowsHook
        {
            get
            {
                if (RecordSettings == null) return mKeyboardHook;
                
                if (RecordSettings.RecordType == EnumRecordType.RecordOnKeyPressed)
                    return mKeyboardHook;

                if (RecordSettings.RecordType == EnumRecordType.RecordOnMouseClick)
                    return mMouseHook;

                return null;
            }
        }

        static RecordingManager()
        {
            mKeyboardHook = new WindowsHooks(HookType.WH_KEYBOARD_LL);
            mMouseHook = new WindowsHooks(HookType.WH_MOUSE_LL);

            mKeyboardHook.HookInvoked += new WindowsHooks.HookEventHandler(mKeyboardHook_HookInvoked);
            mMouseHook.HookInvoked += new WindowsHooks.HookEventHandler(mMouseHook_HookInvoked);
        }

        static void mMouseHook_HookInvoked(object sender, HookEventArgs e)
        {
            if (e.HookCode == 0) //HC_ACTION
            {
                if (e.wParam == (IntPtr)WindowsHooks.WM_LBUTTONDOWN)
                {
                    Bitmap screen = ScreenRecorder.CaptureScreen();
                    if (screen != null)
                        mImages.Add(screen);
                }
            }
        }

        static void mKeyboardHook_HookInvoked(object sender, HookEventArgs e)
        {
            if (e.HookCode == 0) //HC_ACTION
            {
                if (e.wParam == (IntPtr)WindowsHooks.WM_KEYUP || e.wParam == (IntPtr)WindowsHooks.WM_SYSKEYUP)
                {
                    KBDLLHOOKSTRUCT kbStruct = new KBDLLHOOKSTRUCT();
                    Marshal.PtrToStructure(e.lParam, kbStruct);

                    if ((((int)kbStruct.flags & (int)KBDLLHOOKSTRUCTFlags.LLKHF_ALTDOWN) == (int)KBDLLHOOKSTRUCTFlags.LLKHF_ALTDOWN) && kbStruct.vkCode == VK_SNAPSHOT) //Alt + PrintScreen clicked
                    {
                        Bitmap screen = ScreenRecorder.CaptureScreen();
                        if (screen != null)
                            mImages.Add(screen);
                    }                    
                }                
            }
        }

        public static void StartRecording(RecordSettings settings)
        {
            RecordSettings = settings;

            //if already recording stop
            if (mStatus == EnumRecordingStatus.InProgress) return;

            CurrentWindowsHook.Install();
        }

        public static void PauseRecording()
        {
            mStatus = EnumRecordingStatus.Paused;
            CurrentWindowsHook.Uninstall();
        }

        public static Bitmap[] EndRecording()
        {
            mStatus = EnumRecordingStatus.Stopped;
            CurrentWindowsHook.Uninstall();
            Bitmap[] result = mImages.ToArray();

            mImages.Clear();
            return result;
        }
    }
}
